package com.atguigu.tingshu.user.service.impl;

import com.atguigu.tingshu.album.client.AlbumInfoFeignClient;
import com.atguigu.tingshu.album.client.TrackInfoFeignClient;
import com.atguigu.tingshu.common.result.Result;
import com.atguigu.tingshu.common.util.AuthContextHolder;
import com.atguigu.tingshu.model.album.TrackInfo;
import com.atguigu.tingshu.user.login.client.LoginClient;
import com.atguigu.tingshu.user.login.enums.LoginType;
import com.atguigu.tingshu.user.mapper.UserInfoMapper;
import com.atguigu.tingshu.user.mapper.UserPaidAlbumMapper;
import com.atguigu.tingshu.user.service.UserCollectService;
import com.atguigu.tingshu.user.service.UserInfoService;
import com.atguigu.tingshu.user.service.UserPaidTrackService;
import com.atguigu.tingshu.user.service.UserSubscribeService;
import com.atguigu.tingshu.vo.album.AlbumListVo;
import com.atguigu.tingshu.vo.base.user.*;
import com.atguigu.tingshu.vo.user.LoginVo;
import com.atguigu.tingshu.vo.user.UserCollectVo;
import com.atguigu.tingshu.vo.user.UserInfoVo;
import com.atguigu.tingshu.vo.user.UserSubscribeVo;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.joda.time.DateTime;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.Assert;

import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.ZoneOffset;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;

@Slf4j
@Service
@SuppressWarnings({"unchecked", "rawtypes"})
public class UserInfoServiceImpl extends ServiceImpl<UserInfoMapper, UserInfo> implements UserInfoService {
    @Resource
    private UserSubscribeService userSubscribeService;
    @Resource
    private AlbumInfoFeignClient albumInfoFeignClient;
    @Resource
    private UserCollectService userCollectService;
    @Resource
    private LoginClient loginClient;
    @Resource
    private UserPaidAlbumMapper userPaidAlbumMapper;
    @Resource
    private UserPaidTrackService userPaidTrackService;
    @Resource
    private TrackInfoFeignClient trackInfoFeignClient;

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Map<String, String> wxLogin(String code) {
        LoginVo loginVo = new LoginVo();
        loginVo.setCode(code);
        return loginClient.login(LoginType.WECHAT, loginVo);
    }

    @Override
    public UserInfoVo getUserInfo(Long userId) {
        UserInfo userInfo = getById(userId);
        UserInfoVo userInfoVo = new UserInfoVo();
        BeanUtils.copyProperties(userInfo, userInfoVo);
        return userInfoVo;
    }

    @Override
    public void updateUser(UserInfoVo userInfoVo) {
        Long userId = AuthContextHolder.getUserId();
        UserInfo userInfo = getById(userId);
        userInfo.setNickname(userInfoVo.getNickname());
        userInfo.setAvatarUrl(userInfoVo.getAvatarUrl());
        updateById(userInfo);
    }

    @Override
    public Page<UserSubscribeVo> findUserSubscribePage(Long userId, Long page, Long limit) {
        Page<UserSubscribeVo> iPage = new Page<>(page, limit);
        List<UserSubscribe> list = userSubscribeService.list(new LambdaQueryWrapper<UserSubscribe>().eq(UserSubscribe::getUserId, userId));
        List<UserSubscribeVo> userSubscribeVos = new ArrayList<>();
        list.forEach(userSubscribe -> {
            Result<AlbumListVo> userAlbumR = albumInfoFeignClient.findUserAlbum(userSubscribe.getAlbumId());
            Assert.notNull(userAlbumR, "分页查询订阅信息时，远程调用获取专辑信息接口失败！");
            AlbumListVo albumListVo = userAlbumR.getData();

            UserSubscribeVo userSubscribeVo = new UserSubscribeVo();
            BeanUtils.copyProperties(albumListVo, userSubscribeVo);
            userSubscribeVos.add(userSubscribeVo);
        });
        iPage.setRecords(userSubscribeVos);
        return iPage;
    }

    @Override
    public boolean isSubscribe(Long userId, Long albumId) {
        UserSubscribe userSubscribe = userSubscribeService.getOne(new LambdaQueryWrapper<UserSubscribe>()
                .eq(UserSubscribe::getUserId, userId).eq(UserSubscribe::getAlbumId, albumId));
        if (userSubscribe != null) {
            return true;
        }
        return false;
    }

    @Override
    public Page<UserCollectVo> findUserCollectPage(Long userId, Long page, Long limit) {
        Page<UserCollectVo> iPage = new Page<>(page, limit);
        List<UserCollect> list = userCollectService.list(new LambdaQueryWrapper<UserCollect>()
                .eq(UserCollect::getUserId, userId));
        List<UserCollectVo> userCollectVos = new ArrayList<>();
        list.forEach(userCollect -> {
            Result<TrackInfo> trackInfoResult = trackInfoFeignClient.getTrackInfo(userCollect.getTrackId());
            Assert.notNull(trackInfoResult, "分页查询收藏信息时,远程调用获取声音信息失败！");
            TrackInfo trackInfo = trackInfoResult.getData();

            UserCollectVo userCollectVo = new UserCollectVo();
            BeanUtils.copyProperties(trackInfo, userCollectVo);
            userCollectVo.setTrackId(userCollect.getTrackId());
            userCollectVos.add(userCollectVo);
        });
        iPage.setRecords(userCollectVos);
        return iPage;
    }

    @Override
    public boolean isPayAlbum(Long albumId) {
        Long userId = AuthContextHolder.getUserId();
        return userPaidAlbumMapper.selectCount(new LambdaQueryWrapper<UserPaidAlbum>()
                .eq(UserPaidAlbum::getAlbumId, albumId).eq(UserPaidAlbum::getUserId, userId)) == 1;

    }

    @Override
    public List<UserPaidTrack> isPayTrack(Long albumId) {
        Long userId = AuthContextHolder.getUserId();
        return userPaidTrackService.list(new LambdaQueryWrapper<UserPaidTrack>()
                .eq(UserPaidTrack::getAlbumId, albumId).eq(UserPaidTrack::getUserId, userId));
    }

    @Override
    public UserCollect isCollect(Long trackId) {
        Long userId = AuthContextHolder.getUserId();
        return userCollectService.getOne(new LambdaQueryWrapper<UserCollect>().eq(UserCollect::getUserId, userId)
                .eq(UserCollect::getTrackId, trackId));
    }

    @Override
    public void updateVipStatus() {
        LocalDateTime dateTime = LocalDateTime.of(LocalDate.now(), LocalTime.MIN);
        Date date = Date.from(dateTime.toInstant(ZoneOffset.UTC));
        this.update(new LambdaUpdateWrapper<UserInfo>().eq(UserInfo::getIsVip, 1)
                .le(UserInfo::getVipExpireTime, date).set(UserInfo::getIsVip, 0));
    }
}
